/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import core.Problem;
import domain.Domain;
import expression.Alias;
import expression.IntExpr;
import expression.Value;
import expression.And;
import expression.Leq;
import expression.Lt;
import expression.Neq;
import expression.Sum;
import expression.VarInDomain;
import expression.Variable;
import heuristic.ValueHeuristic;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author David
 */
public class Main {
    public static void main(String[] args) {
        nQueen(8);
    }
    
    public static void nQueen(int n) {
        Problem pb = new Problem(new ValueHeuristic());
        
        Variable[] variables = new Variable[n];
        List<IntExpr> csts = new ArrayList<IntExpr>();

        
        for (int i = 0; i < n; i++) {
            variables[i] = pb.createVariable("Q" + i);
            VarInDomain cst = pb.createVarInDomain(variables[i], new Domain(0, n-1));
            csts.add(cst);
        }
                
        for (int i = 0; i < n-1; i++) {
            for (int j = i +1; j < n; j++) {
                // ligne
                Neq neq = pb.createNeq(variables[i], variables[j]);
                csts.add(neq);
                
                // diag 1
                Neq neq1 = pb.createNeq(variables[i], pb.createSum(variables[j], j-i));
                csts.add(neq1);                
                
                // diag 2
                Neq neq2 = pb.createNeq(variables[i], pb.createSum(variables[j], -j+i));
                csts.add(neq2);
            }
        }
        
        IntExpr[] temp = new IntExpr[csts.size()];
        csts.toArray(temp);
        And and = pb.createAnd(temp);
        
        pb.setConstraint(and);
        
        System.out.println(pb);
        System.out.println("##################################################");
        pb.solve();
        System.out.println(pb.getSolution());
    }
    
    public static void test_3() {
        Problem pb = new Problem();
        
        Variable a = pb.createVariable("a");
        Variable b = pb.createVariable("b");
        
        Value v10 = pb.createValue(10);
        Value v20 = pb.createValue(20);
        
        Leq le1 = pb.createLeq(a, v20);
        Leq le2 = pb.createLeq(v10, a);

        Leq le3 = pb.createLeq(b, v20);
        Leq le4 = pb.createLeq(v10, b);

        Lt lt1 = pb.createLt(a, b);
        Lt lt2 = pb.createLt(b, a);
        
        IntExpr[] temp = {le1, le2, le3, le4, lt1, lt2};
        And and = pb.createAnd(temp);
        
        pb.setConstraint(and);
        
        System.out.println("\n" + pb);
        if (pb.solve()) {
            System.out.println(pb);
        }
    }
    
    public static void test_2() {
        Problem pb = new Problem();
        
        Variable v = pb.createVariable("v");
        Value v100 = pb.createValue(100);
        Value v200 = pb.createValue(200);
        
        Leq l1 = pb.createLeq(v, v200);
        Leq l2 = pb.createLeq(v100, v);
       
        And and = pb.createAnd(l1, l2);
        
        pb.setConstraint(and);
        
        System.out.println("\n" + pb);
        if (pb.solve()) {
            System.out.println(pb);
        }
    }
    
    public static void test_1() {
        Problem pb = new Problem();
        
        Variable a = pb.createVariable("a");
        Variable b = pb.createVariable("b");
        
        IntExpr[] p1 = {a, b};
        Sum sum1 = pb.createSum(p1);
        
        Alias a1 = pb.createAlias("sum", sum1);
        
        Value v0 = pb.createValue(0);
        
        Leq l0 = pb.createLeq(v0, a);

        Value v20 = pb.createValue(20);
        
        Leq l1 = pb.createLeq(a1, v20);
        
        Value v10 = pb.createValue(10);
        
        Leq l2 = pb.createLeq(v10, a1);
        
        Leq l3 = pb.createLeq(v0, b);

        IntExpr[] p3 = {l0, l1, l2, l3};
        And inter = pb.createAnd(p3);
        
        pb.setConstraint(inter);
        
        System.out.println("\n" + pb);
        if (pb.solve()) {
            System.out.println(pb);
        }
    }
}
